from abc import ABC, abstractmethod

class Command(ABC):
    """
    抽象命令类，定义了所有命令的接口
    """
    ## 执行命令的方法,返回整形类型
    @abstractmethod
    @staticmethod
    def execute(args) -> int:
        """
        执行命令的方法
        """
        pass

    ## 获取命令名称的方法,返回字符串类型
    @abstractmethod
    @staticmethod
    def get_name() -> str:
        """
        获取命令名称的方法
        """
        pass

    ## 获取命令描述的方法,返回字符串类型
    @abstractmethod
    @staticmethod
    def get_description() -> str:
        """
        获取命令描述的方法
        """
        pass

    ## 命令自身解析参数的方法,接受一个参数列表,返回一个字典类型
    @abstractmethod
    @staticmethod
    def get_arguments(args: list, short_dict: dict = None, arg_config: dict = None) -> dict:
        """
        @param args: 命令行参数列表
        @param short_dict: 短参数与长参数的映射字典
        @param arg_config: 参数配置kv字典,key为参数名,value为一个[bool,str]的列表,第一个bool表示是否为多值参数,第二个str表示参数类型,目前支持int、float、str三种类型
        @return: 参数字典
        @warning: 该方法目前无法处理负数参数值,负数参数值会被当作新的参数名
        """
        ret = {}
        arg_type = None
        cur_key = None
        for arg in args:
            # 处理新的参数名
            if arg.startswith("--"):
                arg = arg[2:]
                if arg not in arg_config:
                    raise ValueError(f"Unknown argument: {arg}")
                cur_key = arg
                arg_type = arg_config[arg][1]
            # 处理短参数名
            elif arg.startswith("-"):
                arg = arg[1:]
                if arg not in short_dict:
                    raise ValueError(f"Unknown argument: {arg}")
                cur_key = short_dict[arg]
                arg_type = arg_config[cur_key][1]
            # 处理参数值
            else:
                value = arg if arg_type is str else arg_type(arg)
                is_list = arg_config[cur_key][0]
                if is_list and cur_key in ret:
                    ret[cur_key].append(value)
                elif is_list and cur_key not in ret:
                    ret[cur_key] = [value]
                elif not is_list and cur_key not in ret:
                    ret[cur_key] = value
                else:
                    raise ValueError(f"Argument {cur_key} already has a value: {ret[cur_key]}")
     
                        
        return ret


class DemoInterface(ABC):
    
    @abstractmethod
    def get_str(self,cus) -> str:
        """
        获取字符串的方法
        """
        # 连接cus与["hello"]
        return cus + ["hello"]